package com.example.demo.algorithm.delay_queue;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Set;

/**
 * Redis sorted set
 * Redis的数据结构Zset，同样可以实现延迟队列的效果，主要利用它的score属性，redis通过score来为集合中的成员进行从小到大的排序。
 *
 * 通过zadd命令向队列delayqueue 中添加元素，并设置score值表示元素过期的时间；向delayqueue 添加三个order1、order2、order3，分别是10秒、20秒、30秒后过期。
 *
 *  zadd delayqueue 3 order3
 *
 *  消费端轮询队列delayqueue， 将元素排序后取最小时间与当前时间比对，如小于当前时间代表已经过期移除key。
 */
public class PollOrderQueue {

    @Resource
    Jedis jedis;

    public void pollOrderQueue(String[] args) throws InterruptedException {
        while(true){
            Set<Tuple> set = jedis.zrangeByScoreWithScores("delayqueue", 0, System.currentTimeMillis());

            String value = ((Tuple)set.toArray()[0]).getElement();
            int score = (int)((Tuple)set.toArray()[0]).getScore();

            Calendar cal = Calendar.getInstance();
            int nowSecond = (int) (cal.getTimeInMillis()/1000);

            if(nowSecond < score){
                jedis.zrem("delayqueue", value);
                System.out.println("order:" + value + " will be processed");
            }

            if(jedis.zcard("delayqueue") <= 0){
                System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + " delayqueue is empty");
                return;
            }
            Thread.sleep(1000);
        }
    }
}
